x86, hvm: Allow stdvga acceleration to work with 32-bit x86.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 16 Nov 2007 14:40:22 +0000 (14:40 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 16 Nov 2007 14:40:22 +0000 (14:40 +0000)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/Makefile
xen/arch/x86/hvm/stdvga.c
xen/include/asm-x86/hvm/io.h

index 514ca34a1b70122c3ca4ce03157bb66bb3b652b3..bb2e0e42c18a673caa5fa7ab22924a7683ec295c 100644 (file)
@@ -17,5 +17,4 @@ obj-y += vioapic.o
 obj-y += vlapic.o
 obj-y += vpic.o
 obj-y += save.o
-
-obj-$(x86_64) += stdvga.o
+obj-y += stdvga.o
index e068c31a0c77b5a526e2a239cdffbff75330e6ef..9456df84a7b75805ded040ec4993680496432f3d 100644 (file)
 #include <xen/config.h>
 #include <xen/types.h>
 #include <xen/sched.h>
+#include <xen/domain_page.h>
 #include <asm/hvm/support.h>
 
-#define vram_b(_s, _a) \
-    (((uint8_t*) (_s)->vram_ptr[((_a)>>12)&0x3f])[(_a)&0xfff])
-#define vram_w(_s, _a) \
-    (((uint16_t*)(_s)->vram_ptr[((_a)>>11)&0x3f])[(_a)&0x7ff])
-#define vram_l(_s, _a) \
-    (((uint32_t*)(_s)->vram_ptr[((_a)>>10)&0x3f])[(_a)&0x3ff])
-
 #define PAT(x) (x)
 static const uint32_t mask16[16] = {
     PAT(0x00000000),
@@ -83,6 +77,25 @@ const uint8_t gr_mask[16] = {
     (uint8_t)~0x00, /* 0x08 */
 };
 
+static uint8_t *vram_getb(struct hvm_hw_stdvga *s, unsigned int a)
+{
+    struct page_info *pg = s->vram_page[(a >> 12) & 0x3f];
+    uint8_t *p = map_domain_page(page_to_mfn(pg));
+    return &p[a & 0xfff];
+}
+
+static uint32_t *vram_getl(struct hvm_hw_stdvga *s, unsigned int a)
+{
+    struct page_info *pg = s->vram_page[(a >> 10) & 0x3f];
+    uint32_t *p = map_domain_page(page_to_mfn(pg));
+    return &p[a & 0x3ff];
+}
+
+static void vram_put(struct hvm_hw_stdvga *s, void *p)
+{
+    unmap_domain_page(p);
+}
+
 static uint64_t stdvga_inb(uint64_t addr)
 {
     struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
@@ -190,20 +203,9 @@ static void stdvga_outb(uint64_t addr, uint8_t val)
         break;
 
     case 0x3cf:                 /* graphics data register */
+        s->gr[s->gr_index] = val;
         if ( s->gr_index < sizeof(gr_mask) )
-        {
-            s->gr[s->gr_index] = val & gr_mask[s->gr_index];
-        }
-        else if ( (s->gr_index == 0xff) && (s->vram_ptr != NULL) )
-        {
-            uint32_t addr;
-            for ( addr = 0xa0000; addr < 0xa4000; addr += 2 )
-                vram_w(s, addr) = (val << 8) | s->gr[0xfe];
-        }
-        else
-        {
-            s->gr[s->gr_index] = val;
-        }
+            s->gr[s->gr_index] &= gr_mask[s->gr_index];
         break;
     }
 
@@ -326,7 +328,8 @@ static uint8_t stdvga_mem_readb(uint64_t addr)
 {
     struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
     int plane;
-    uint32_t ret;
+    uint32_t ret, *vram_l;
+    uint8_t *vram_b;
 
     addr &= 0x1ffff;
     if ( addr >= 0x10000 )
@@ -335,18 +338,24 @@ static uint8_t stdvga_mem_readb(uint64_t addr)
     if ( s->sr[4] & 0x08 )
     {
         /* chain 4 mode : simplest access */
-        ret = vram_b(s, addr);
+        vram_b = vram_getb(s, addr);
+        ret = *vram_b;
+        vram_put(s, vram_b);
     }
     else if ( s->gr[5] & 0x10 )
     {
         /* odd/even mode (aka text mode mapping) */
         plane = (s->gr[4] & 2) | (addr & 1);
-        ret = vram_b(s, ((addr & ~1) << 1) | plane);
+        vram_b = vram_getb(s, ((addr & ~1) << 1) | plane);
+        ret = *vram_b;
+        vram_put(s, vram_b);
     }
     else
     {
         /* standard VGA latched access */
-        s->latch = vram_l(s, addr);
+        vram_l = vram_getl(s, addr);
+        s->latch = *vram_l;
+        vram_put(s, vram_l);
 
         if ( !(s->gr[5] & 0x08) )
         {
@@ -401,7 +410,8 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
 {
     struct hvm_hw_stdvga *s = &current->domain->arch.hvm_domain.stdvga;
     int plane, write_mode, b, func_select, mask;
-    uint32_t write_mask, bit_mask, set_mask;
+    uint32_t write_mask, bit_mask, set_mask, *vram_l;
+    uint8_t *vram_b;
 
     addr &= 0x1ffff;
     if ( addr >= 0x10000 )
@@ -413,8 +423,13 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
         plane = addr & 3;
         mask = (1 << plane);
         if ( s->sr[2] & mask )
-            vram_b(s, addr) = val;
-    } else if ( s->gr[5] & 0x10 )
+        {
+            vram_b = vram_getb(s, addr);
+            *vram_b = val;
+            vram_put(s, vram_b);
+        }
+    }
+    else if ( s->gr[5] & 0x10 )
     {
         /* odd/even mode (aka text mode mapping) */
         plane = (s->gr[4] & 2) | (addr & 1);
@@ -422,7 +437,9 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
         if ( s->sr[2] & mask )
         {
             addr = ((addr & ~1) << 1) | plane;
-            vram_b(s, addr) = val;
+            vram_b = vram_getb(s, addr);
+            *vram_b = val;
+            vram_put(s, vram_b);
         }
     }
     else
@@ -491,9 +508,9 @@ static void stdvga_mem_writeb(uint64_t addr, uint32_t val)
         /* mask data according to sr[2] */
         mask = s->sr[2];
         write_mask = mask16[mask];
-        vram_l(s, addr) =
-            (vram_l(s, addr) & ~write_mask) |
-            (val & write_mask);
+        vram_l = vram_getl(s, addr);
+        *vram_l = (*vram_l & ~write_mask) | (val & write_mask);
+        vram_put(s, vram_l);
     }
 }
 
@@ -661,30 +678,33 @@ int stdvga_intercept_mmio(ioreq_t *p)
 
 void stdvga_init(struct domain *d)
 {
-    int i;
     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
+    struct page_info *pg;
+    void *p;
+    int i;
+
     memset(s, 0, sizeof(*s));
     spin_lock_init(&s->lock);
     
-    for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
+    for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ )
     {
-        struct page_info *vram_page;
-        vram_page = alloc_domheap_page(NULL);
-        if ( vram_page == NULL )
+        if ( (pg = alloc_domheap_page(NULL)) == NULL )
             break;
-        s->vram_ptr[i] = page_to_virt(vram_page);
-        memset(s->vram_ptr[i], 0, PAGE_SIZE);
+        s->vram_page[i] = pg;
+        p = map_domain_page(page_to_mfn(pg));
+        clear_page(p);
+        unmap_domain_page(p);
     }
 
-    if ( i == ARRAY_SIZE(s->vram_ptr) )
+    if ( i == ARRAY_SIZE(s->vram_page) )
     {
         /* Sequencer registers. */
         register_portio_handler(d, 0x3c4, 2, stdvga_intercept_pio);
         /* Graphics registers. */
         register_portio_handler(d, 0x3ce, 2, stdvga_intercept_pio);
         /* MMIO. */
-        register_buffered_io_handler(d, 0xa0000, 0x10000,
-                                     stdvga_intercept_mmio);
+        register_buffered_io_handler(
+            d, 0xa0000, 0x10000, stdvga_intercept_mmio);
     }
 }
 
@@ -693,13 +713,11 @@ void stdvga_deinit(struct domain *d)
     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
     int i;
 
-    for ( i = 0; i != ARRAY_SIZE(s->vram_ptr); i++ )
+    for ( i = 0; i != ARRAY_SIZE(s->vram_page); i++ )
     {
-        struct page_info *vram_page;
-        if ( s->vram_ptr[i] == NULL )
+        if ( s->vram_page[i] == NULL )
             continue;
-        vram_page = virt_to_page(s->vram_ptr[i]);
-        free_domheap_page(vram_page);
-        s->vram_ptr[i] = NULL;
+        free_domheap_page(s->vram_page[i]);
+        s->vram_page[i] = NULL;
     }
 }
index 1a0287a884a1ba57250fe2a17eb8b05cbdb7a0a6..daea36d3bb3f3d6a040de2d9c0f78fa4ac3b354f 100644 (file)
@@ -159,8 +159,6 @@ extern void hvm_io_assist(void);
 extern void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
                          union vioapic_redir_entry *ent);
 
-#ifdef __x86_64__
-
 struct hvm_hw_stdvga {
     uint8_t sr_index;
     uint8_t sr[0x18];
@@ -169,20 +167,12 @@ struct hvm_hw_stdvga {
     uint32_t latch;
     int stdvga;
     int cache;
-    uint8_t *vram_ptr[64];  /* shadow of 0xa0000-0xaffff */
+    struct page_info *vram_page[64];  /* shadow of 0xa0000-0xaffff */
     spinlock_t lock;
 };
 
 void stdvga_init(struct domain *d);
 void stdvga_deinit(struct domain *d);
 
-#else /* __i386__ */
-
-struct hvm_hw_stdvga {};
-#define stdvga_init(d)   ((void)0)
-#define stdvga_deinit(d) ((void)0)
-
-#endif
-
 #endif /* __ASM_X86_HVM_IO_H__ */